package com.pingpang.websocketchat;

import java.net.InetSocketAddress;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.pingpang.websocketchat.send.impl.ChatSendUtil;

import io.netty.channel.Channel;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
import io.netty.handler.timeout.IdleState;
import io.netty.handler.timeout.IdleStateEvent;

/** 
 * 处理TextWebSocketFrame
 */
public class TextWebSocketFrameHandler extends SimpleChannelInboundHandler<TextWebSocketFrame> {

	private int count=0;

	//日志操作
	private Logger logger = LoggerFactory.getLogger(TextWebSocketFrameHandler.class);
	
	@Override
	protected void channelRead0(ChannelHandlerContext ctx, TextWebSocketFrame msg) throws Exception { // (1)
		InetSocketAddress ipSocket = (InetSocketAddress)ctx.channel().remoteAddress();
	    String clientIp = ipSocket.getAddress().getHostAddress();
	    logger.info("客户端ip地址："+clientIp);
		
		if("ping".equals(msg.text())) {
			ctx.channel().writeAndFlush(new TextWebSocketFrame("pong"));
			count=0;
			return;
		}
		
		if("Heartbeat".equals(msg.text())) {
			count=0;
			return;	
		}
		
		ChatSendUtil.getChatSend(msg.text(), ctx);
		
	}

	@Override
	public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
		if (evt instanceof IdleStateEvent) {
			IdleStateEvent event = (IdleStateEvent) evt;
			logger.info(ctx.channel().remoteAddress()+"超时次数:"+count);
			String type = "";
			if (event.state() == IdleState.READER_IDLE) {
				type = "read idle";
				count++;
				if(count>5) {
					 logger.info("超时次数达到最大值了，断开连接");
		              ChannelManager.removeChannelByChannel(ctx.channel());
		              ctx.channel().close();
					}
			} else if (event.state() == IdleState.WRITER_IDLE) {
				type = "write idle";
				count=0;
			} else if (event.state() == IdleState.ALL_IDLE) {
				type = "all idle";
				count=0;
			}
			ctx.writeAndFlush(new TextWebSocketFrame("Heartbeat")).addListener(ChannelFutureListener.CLOSE_ON_FAILURE);
			logger.info( ctx.channel().remoteAddress()+"超时类型：" + type);
		}
		super.userEventTriggered(ctx, evt);
	}
	
	@Override
	public void handlerAdded(ChannelHandlerContext ctx) throws Exception { // (2)
		Channel incoming = ctx.channel();
		// Broadcast a message to multiple Channels
		// channels.writeAndFlush(new TextWebSocketFrame("[SERVER] - " +
		// incoming.remoteAddress() + " 加入"));

		// channels.add(incoming);
		logger.info("Client:" + incoming.remoteAddress() + "加入");
	}

	@Override
	public void handlerRemoved(ChannelHandlerContext ctx) throws Exception { // (3)
		Channel incoming = ctx.channel();

		// Broadcast a message to multiple Channels
		// channels.writeAndFlush(new TextWebSocketFrame("[SERVER] - " +
		// incoming.remoteAddress() + " 离开"));

		logger.info("Client:" + incoming.remoteAddress() + "离开");
		ChannelManager.removeChannelByChannel(incoming);
		// A closed Channel is automatically removed from ChannelGroup,
		// so there is no need to do "channels.remove(ctx.channel());"
	}

	@Override
	public void channelActive(ChannelHandlerContext ctx) throws Exception { // (5)
		Channel incoming = ctx.channel();
		logger.info("Client:" + incoming.remoteAddress() + "在线");
	}

	@Override
	public void channelInactive(ChannelHandlerContext ctx) throws Exception { // (6)
		Channel incoming = ctx.channel();
		logger.info("Client:" + incoming.remoteAddress() + "掉线");
		ChannelManager.removeChannelByChannel(incoming);
	}

	@Override
	public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) // (7)
			throws Exception {
		Channel incoming = ctx.channel();
		logger.info("Client:" + incoming.remoteAddress() + "异常");
		// 当出现异常就关闭连接
		cause.printStackTrace();
		ctx.close();
	}

}
